package com.surpassun.emall.service.impl;

import java.security.SecureRandom;
import java.util.Date;
import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import com.surpassun.emall.model.Address;
import com.surpassun.emall.model.Role;
import com.surpassun.emall.model.Store;
import com.surpassun.emall.model.User;
import com.surpassun.emall.repository.UserRepository;
import com.surpassun.emall.service.UserService;
import com.surpassun.emall.util.PasswordUtil;
import com.surpassun.emall.util.Validator;

/**
 *
 * @author Denis
 */
@Service
public class UserServiceImpl extends AbstractServiceImpl<User> implements UserService {

	@Inject
	UserRepository userRepository;
	
    public UserServiceImpl() {
    	super(User.class);
    }
    
    /**
     * Override the method to force the validation
     */
    @Override
    public void add(User user) {
    	if (Validator.isNotNull(user) &&
    		validateUser(user.getFirstname(), user.getLastname(), user.getEmail(), user.getPassword())) {
    		user.setPassword(PasswordUtil.encrypt(user.getPassword()));
    		userRepository.add(user);
    	}
    }
    
    @Override
    public void add(String title, String firstname, String lastname, String email, String password,
    		String phone, boolean active, Address address, List<Role> roles) {
    	if (validateUser(firstname, lastname, email, password)) {
    		String encryptedPassword = PasswordUtil.encrypt(password);
    		User user = new User(title, new Date(), firstname, lastname, email, encryptedPassword, phone, null, null, active, address, roles);
    		userRepository.add(user);
    	}
    }
    
    /**
     * Override the method to force the validation
     */
    @Override
    public void update(User user) {
    	if (Validator.isNotNull(user) &&
        	validateUser(user.getFirstname(), user.getLastname(), user.getEmail(), user.getPassword())) {
    		user.setPassword(PasswordUtil.encrypt(user.getPassword()));
    		userRepository.update(user);
    	}
    }

	@Override
	public void update(User user, String title, String firstname, String lastname, String email, String password,
    		String phone, String lastLoginIP, Date lastLoginDate, boolean active, Address address, List<Role> roles, List<Store> stores) {
		if (Validator.isNotNull(user) && validateUser(firstname, lastname, email, password)) {
			user.setTitle(title);
			user.setFirstname(firstname);
			user.setLastname(lastname);
			user.setEmail(email);
			user.setPassword(PasswordUtil.encrypt(user.getPassword()));
			user.setPhone(phone);
			user.setLastLoginIP(lastLoginIP);
			user.setLastLoginDate(lastLoginDate);
			user.setActive(active);
			user.setAddress(address);
			user.setRoles(roles);
			user.setStores(stores);
			userRepository.update(user);
		}
	}
	
	@Override
	public User getUserByEmail(String email) {
		return userRepository.getUserByEmail(email);
	}
    
    private boolean validateUser(String firstname, String lastname, String email, String password) {
    	return (Validator.isNotNull(firstname) && Validator.isNotNull(lastname)
    			&& Validator.isNotNull(email) && Validator.isNotNull(password));
    }

    /**
     * If there is a user with the email in the database
     * then the service will encrypt the password entered by the user and compare it with the encrypted password saved in the database
     * If everything matches and the user is active, update the user's last login information and return the user object
     */
	@Override
	public User login(String email, String password, String ip) {
		User user = userRepository.getUserByEmail(email);
		if (Validator.isNotNull(user)) {
			String encryptedPassword = user.getPassword();
			//compare the password after encryption
			if (PasswordUtil.encrypt(password).equals(encryptedPassword) && user.isActive()) {
				//update the last login information
				user.setLastLoginDate(new Date());
				user.setLastLoginIP(ip);
				userRepository.update(user);
				return user;
			}
		}
		return null;
	}

	@Override
	public void updatePassword(User user, String password) {
		String encryptedPassword = PasswordUtil.encrypt(password);
		user.setPassword(encryptedPassword);
		userRepository.update(user);
	}

	@Override
	public String resetPassword(User user) {
		byte[] bytes = new byte[8];
		SecureRandom random = new SecureRandom();
		random.nextBytes(bytes);
		String newPassword = bytes.toString();
		updatePassword(user, newPassword);
		return newPassword;
	}
}
